const text = "𠮷"; //占用了两个码元（32位）

// 这种情况下，打印输出没有问题，但是字符串的长度以及charAt，charCodeAt方法会有问题
// 下面给出了使用codePointAt方法得到的校正的字符串长度以及获取索引位字符的方法

console.log(text);

console.log(new String(text));


console.log(text[0]);  // 这种输出方式会出现bug，因为是按照码元来读取字符的，32位的字符占用两个码元，第一个码元不对应字符
console.log(text.charAt(0));
console.log("字符串长度：", text.length);
console.log("使用正则测试：", /^.$/.test(text));
console.log("使用正则测试：", /^.$/u.test(text)); // 解决正则表达式使用 u flag
console.log(text.match(/^.$/ug));
console.log("得到第一个码元：", text.charCodeAt(0));
console.log("得到第二个码元：", text.charCodeAt(1));

//𠮷：\ud842\udfb7
console.log("得到第一个码点：", text.codePointAt(0));
console.log("得到第二个码点：", text.codePointAt(1));

/**
 * 判断字符串str，是32位，还是16位
 * @param {String} str 
 */
function is32bit(str, i) {
    //如果码点大于了16位二进制的最大值，则其是32位的
    return str.codePointAt(i) > 0xffff;
}

/**
 * 得到一个字符串的真实长度
 * @param {String} str 
 */
function getTrueLen(str) {
    let len = str.length;
    for(let i = 0; i < str.length; i ++) {
        if(is32bit(str, i)) {
            len --;
        }
    }
    return len;
}

function getLengthOfCodePoint(str) {
    var len = 0;
    for (let i = 0; i < str.length; i++) {
        //i在索引码元
        if (is32bit(str, i)) {
            //当前字符串，在i这个位置，占用了两个码元
            i++;
        }
        len++;
    }
    return len;
}

console.log("𠮷是否是32位的：", is32bit("𠮷", 0))
console.log("ab𠮷ab的码点长度：", getLengthOfCodePoint("ab𠮷ab"));
console.log("ab𠮷ab的码点长度：", getTrueLen("ab𠮷ab"));


function myCharCodeAt(str, index) {
    let len = 0;
    let myCharCode;
    for(let i = 0; i < str.length; i ++) {
        if(index == len) {
            myCharCode = str.codePointAt(i);
        }
        if(is32bit(str, i)) {
            i++;
        }
        len++;
    }
    let char = String.fromCodePoint(myCharCode);
    return {
        char: char,
        myCharCode: myCharCode
    };
}
console.log(myCharCodeAt("ab𠮷ab", 2));




